<script setup lang="ts">
defineOptions({
  name: "echartsCom"
});
import { ref, computed, onMounted, onUnmounted, nextTick, watch } from "vue";
import { templateRef } from "@vueuse/core";
import { useDark, useECharts, type UtilsEChartsOption } from "@pureadmin/utils";
// import type { EChartsOption } from "echarts/types/dist/shared";
import type { LabelLayoutFunctionType, EchartsInstanceFunctionType } from "@/views/common/components/types";
import type { ECharts } from "echarts";

const { isDark } = useDark();
const theme = computed(() => (isDark.value ? "dark" : "light"));

interface Props {
  /**  获取当前echarts实例对象，参数为实例对象和回调函数 */
  getEchartsInstance?: EchartsInstanceFunctionType | null;
  /**  获取 optiins 配置函数 */
  labelLayoutFn?: LabelLayoutFunctionType | null;
  /**  同 echarts option */
  options?: CommonEcharts.CommonEchartsOption | null;
  /**  同 px-empty image-size */
  imageSize?: number;
}

const props = withDefaults(defineProps<Props>(), {
  imageSize: 100
});

const echartsRef = ref<string>(Math.random().toString(36).slice(2, 10));
const echartsObject = ref<any>(null);
const fnOptions = ref<CommonEcharts.CommonEchartsOption>(null);

const isShowEcharts = computed(() => {
  if (props.labelLayoutFn) {
    return !!fnOptions.value;
  } else {
    return !!props.options;
  }
});

const getEcharts = async (): Promise<any> => {
  if (echartsObject.value) return echartsObject.value;
  echartsObject.value = useECharts(templateRef(echartsRef.value), { theme });
  await nextTick();
  return echartsObject.value;
};

const updateData = async (options: CommonEcharts.CommonEchartsOption): Promise<ECharts> => {
  await nextTick();
  const { setOptions, clear, resize, getInstance } = echartsObject.value;
  clear();
  setOptions(options);
  await nextTick();
  resize();
  return getInstance();
};

const initData = async (flag?: boolean) => {
  await nextTick();
  const { setOptions, clear, resize, getInstance } = echartsObject.value;
  clear();
  if (props.labelLayoutFn) {
    fnOptions.value = await props.labelLayoutFn(echartsObject.value);
    fnOptions.value && (flag ? setOptions(fnOptions.value, flag) : setOptions(fnOptions.value));
  } else {
    props.options && (flag ? setOptions(props.options, flag) : setOptions(props.options));
  }
  await nextTick();
  props.getEchartsInstance && props.getEchartsInstance(getInstance(), (o: CommonEcharts.CommonEchartsOption) => updateData(o));
  resize();
  window.addEventListener("resize", () => resize());
};

watch(
  () => props.options,
  async val => {
    if (val) {
      await getEcharts();
      await initData();
    }
  },
  { immediate: true, deep: true }
);

onMounted(async () => {
  await getEcharts();
  await initData();
});

onUnmounted(() => {
  window.onresize = () => null;
});

defineExpose({
  echartsRef: templateRef(echartsRef.value),
  echartsObject,
  fnOptions,
  getEcharts,
  initData
});
</script>

<template>
  <div class="echarts-content">
    <div v-if="isShowEcharts" :ref="echartsRef" class="echarts-com" />
    <div v-else class="echarts-empty">
      <px-empty :image-size="imageSize" />
    </div>
  </div>
</template>

<style lang="scss" scoped>
.echarts-content {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;

  .echarts-com {
    display: block;
    width: 100%;
    height: 100%;
    margin: 0, auto;
  }

  .px-empty {
    padding: 0;
  }
}
</style>
